using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using OpenComposite.EII.Repository;

namespace OpenComposite.EII.Forms
{
	public partial class FormCreateNewBase : Form
	{
		#region Initialization
		protected FormCreateNewBase()
		{
			_dtHierarchy = null;
			_allowChangeDomain = true;
			_bShowAllDomains = true;
			_bShowAllFolders = false;
			_bAllowContinue = true;
			_isFormClosing = false;

			_bAddNullFolderItem = false;
			_sNullFolderItem = "";

			_idCurrentDomain = -1;
			//_idFolder = -1;

			_item = null;
			_parentItemNew = null;
			_serviceProvider = null;

			_idRepository = -1;
			_idDomain = -1;

			imageList = Helpers.GetRepositoryItemTypeImageList();

			InitializeComponent();

			this.DialogResult = DialogResult.Cancel;

			tscmbDomain.ComboBox.DrawMode = DrawMode.OwnerDrawFixed;
			tscmbDomain.ComboBox.DrawItem += new DrawItemEventHandler(ComboBox_DrawItem);
			tscmbFolder.ComboBox.DrawMode = DrawMode.OwnerDrawFixed;
			tscmbFolder.ComboBox.DrawItem += new DrawItemEventHandler(ComboBox_DrawItem);

		}
		public FormCreateNewBase(IServiceProvider serviceProvider,
			Repository.RepositoryItemBase item, bool bAllowContinue)
			: this()
		{
			_item = item;
			_folderType = item.RepositoryItemType;
			_serviceProvider = serviceProvider;
			_bAllowContinue = bAllowContinue;

			_idRepository = Global.Status.CurrentRepositoryId;
			_idDomain = -1;//Global.Status.CurrentDomainId;

			tsbtnSaveContinue.Visible = bAllowContinue;
		}
		public FormCreateNewBase(IServiceProvider serviceProvider,
			Repository.RepositoryItemBase item, bool bAllowContinue, ItemType folderType)
			: this()
		{
			_item = item;
			_folderType = folderType;
			_serviceProvider = serviceProvider;
			_bAllowContinue = bAllowContinue;

			_idRepository = Global.Status.CurrentRepositoryId;
			_idDomain = -1;//Global.Status.CurrentDomainId;

			tsbtnSaveContinue.Visible = bAllowContinue;
		}
		#endregion

		#region Public Members

		#region Properties

		[DefaultValue(true), Category("FormCreateNewBase")]
		public bool AllowChangeDomain
		{
			get { return _allowChangeDomain; }
			set { _allowChangeDomain = value; }
		}

		[DefaultValue(true), Category("FormCreateNewBase")]
		public bool ShowAllDomains
		{
			get { return _bShowAllDomains; }
			set { _bShowAllDomains = value; }
		}
		[DefaultValue(false), Category("FormCreateNewBase")]
		public bool ShowAllFolders
		{
			get { return _bShowAllFolders; }
			set { _bShowAllFolders = value; }
		}

		[DefaultValue(true), Category("FormCreateNewBase")]
		public bool FoldersVisible
		{
			get { return tscmbFolder.Enabled; }
			set
			{
				if ( !value && !DomainsVisible ) {
					tscmbFolder.Visible = !value;
					tscmbFolder.Enabled = value;
					tslblFolder.Visible = !value;
				} else {
					tscmbFolder.Visible = value;
					tscmbFolder.Enabled = value;
					tslblFolder.Visible = value;
				}
				//tscmbFolder.Enabled = value;
				//if ( DomainsVisible == value ) {
				//    tsCreateAt.Visible = value;
				//    tsCreateAt.Enabled = value;
				//} else {
				//    tsCreateAt.Visible = !value;
				//    tsCreateAt.Enabled = !value;
				//}
			}
		}
		[DefaultValue(true), Category("FormCreateNewBase")]
		public bool DomainsVisible
		{
			get { return tscmbDomain.Enabled; }
			set
			{
				if ( !value && !FoldersVisible ) {
					tscmbDomain.Visible = !value;
					tscmbDomain.Enabled = value;
					tslblDomain.Visible = !value;
				} else {
					tscmbDomain.Visible = value;
					tscmbDomain.Enabled = value;
					tslblDomain.Visible = value;
				}
				//    tsCreateAt.Visible = value;
				//    tsCreateAt.Enabled = value;
				//} else {
				//    tsCreateAt.Visible = !value;
				//    tsCreateAt.Enabled = !value;
				//}
			}
		}

		[Browsable(false), Category("FormCreateNewBase")]
		public IRepositoryItem ParentItem
		{
			get { return _parentItem; }
			set { _parentItem = value; }
		}

		[DefaultValue(true), Category("FormCreateNewBase")]
		public bool CreateAtToolStripVisible
		{
			get { return tsCreateAt.Visible; }
			set { tsCreateAt.Visible = value; }
		}

		[Browsable(false)]
		public int RepositoryID
		{
			get { return _idRepository; }
			set { _idDomain = value; }
		}
		[Browsable(false)]
		public int DomainID
		{
			get { return _idDomain; }
			set { _idDomain = value; }
		}
		[Browsable(false)]
		public IRepositoryItem NewParentItem
		{
			get { return _parentItemNew; }
			protected set { _parentItemNew = value; }
		}

		#endregion

		#endregion

		#region Protected Members

		#region Constants
		protected const int TextGap = 18;
		protected const int IndentWidth = 10;
		#endregion

		#region Properties

		protected bool IsFormClosing
		{
			get { return _isFormClosing; }
		}

		protected bool AllowContinue
		{
			get { return _bAllowContinue; }
		}

		protected RepositoryItemBase RepositoryItem
		{
			get { return _item; }
		}
		protected RepositoryService RepositoryService
		{
			get { return (RepositoryService)this.GetService(typeof(RepositoryService)); }
		}

		protected ToolStrip MainToolStrip
		{
			get { return tsMain; }
		}
		protected ToolStrip CreateAtToolStrip
		{
			get { return tsCreateAt; }
		}

		protected ToolStripComboBox DomainToolStripComboBox
		{
			get { return tscmbDomain; }
		}
		protected ToolStripComboBox FolderToolStripComboBox
		{
			get { return tscmbFolder; }
		}

		protected bool AddNullFolderItem
		{
			get { return _bAddNullFolderItem; }
			set { _bAddNullFolderItem = value; }
		}
		protected string NullFolderItemText
		{
			get { return _sNullFolderItem; }
			set { _sNullFolderItem = value; }
		}
		#endregion

		#region Methods

		// virtual
		protected virtual void OnDomainSelectedIndexChanged()
		{
			DomainItem di = tscmbDomain.SelectedItem as DomainItem;
			if ( di == null ) {
				_idCurrentDomain = -1;
			} else {
				_idCurrentDomain = di.Item.ID;
				fillFolderComboBox(di);
				if ( tscmbFolder.Items.Count > 0 )
					tscmbFolder.SelectedIndex = 0;
			}
		}
		protected virtual void OnFolderSelectedIndexChanged()
		{
			FolderItem fi = tscmbFolder.SelectedItem as FolderItem;
			if ( fi == null ) {
				this.NewParentItem = null;
			} else {
				this.NewParentItem = fi.Item;
			}
		}
		protected virtual void OnValidateNewItem(CancelEventArgs e)
		{
		}
		protected virtual void OnSaveClose(CancelEventArgs e)
		{
			if ( e.Cancel )
				return;

			this.DomainID = _idCurrentDomain;

			_item.Save();
			this.DialogResult = DialogResult.OK;
			this.Close();
		}
		protected virtual void OnSaveContinue(CancelEventArgs e)
		{
			if ( e.Cancel )
				return;

			this.DomainID = _idCurrentDomain;

			_item.Save();
			this.DialogResult = DialogResult.Retry;
			this.Close();
		}
		protected virtual void OnCancel()
		{
			//_item.DeleteFromDBInternal(false);
			_item.Destroy(false);
			this.DialogResult = DialogResult.Cancel;
			if ( !_isFormClosing )
				this.Close();
		}

		// override
		protected override void OnLoad(EventArgs e)
		{
			if ( !this.DesignMode ) {
				loadRepositoryHierarchy();
				fillDomainList();
				//if ( tscmbDomain.Items.Count > 0 )
				//    tscmbDomain.SelectedIndex = 0;

				selectDomain(this.DomainID);
				if ( this.ParentItem != null ) {
					selectFolderItem(this.ParentItem.RepositoryItemType, this.ParentItem.ID);
				} else if ( tscmbFolder.Items.Count > 0 ) {
					tscmbFolder.SelectedIndex = 0;
				}
			}
			base.OnLoad(e);
		}
		protected override void OnFormClosing(FormClosingEventArgs e)
		{
			if ( _isFormClosing )
				return;
			this.Refresh();
			_isFormClosing = true;
			try {
				if ( e.CloseReason == CloseReason.UserClosing && this.DialogResult == DialogResult.Cancel ) {
					OnCancel();
				}
				base.OnFormClosing(e);
			} finally {
				_isFormClosing = false;
			}
		}

		protected override object GetService(Type service)
		{
			if ( _serviceProvider != null )
				return _serviceProvider.GetService(service);
			else
				return base.GetService(service);
		}
		#endregion

		#region Event Handlers
		#endregion

		#endregion

		#region Private Members

		#region Variables

		private bool _bAllowContinue;
		private bool _allowChangeDomain;
		private bool _bShowAllDomains;
		private bool _bShowAllFolders;
		private bool _isFormClosing;

		private int _idRepository;
		private int _idDomain;
		private int _idCurrentDomain;
		//private int _idFolder;

		private bool _bAddNullFolderItem;
		private string _sNullFolderItem;

		private RepositoryItemBase _item;
		private IRepositoryItem _parentItem;
		private IRepositoryItem _parentItemNew;

		private ItemType _folderType;
		private DataTable _dtHierarchy;

		private IServiceProvider _serviceProvider;

		private ImageList imageList;
		#endregion

		#region Methods
		private void loadRepositoryHierarchy()
		{
			_dtHierarchy = Global.Data.GetRepositoryHierarchy(this.RepositoryID);
			//if ( _dtHierarchy != null )
			//    addDomainIDToRows(_dtHierarchy);
		}

		private void fillDomainList()
		{
			if ( _dtHierarchy == null ) loadRepositoryHierarchy();

			tscmbDomain.BeginUpdate();
			tscmbFolder.BeginUpdate();
			try {
				tscmbDomain.Items.Clear();
				tscmbFolder.Items.Clear();
				// select top domains
				DataRow[] rows;
				rows = _dtHierarchy.Select("parent_reptype_id IS NULL AND parent_id IS NULL AND " +
							 string.Format("child_reptype_id = {0}", (int)ItemType.Domain));

				foreach ( DataRow row in rows ) {
					// add domain to combobox
					addDomainToList(row, 0);
				}

				// auto-width combobox dropdown
				using ( Graphics g = tscmbDomain.ComboBox.CreateGraphics() ) {
					foreach ( DomainItem dom in tscmbDomain.Items ) {
						SizeF sz = g.MeasureString(dom.Text, tscmbDomain.Font);
						int itemwidth = (int)Math.Ceiling(sz.Width) + dom.Indent + TextGap + 18/*scrollbar*/;
						if ( itemwidth > tscmbDomain.DropDownWidth )
							tscmbDomain.DropDownWidth = itemwidth;
					}
				}
			} finally {
				tscmbDomain.EndUpdate();
				tscmbFolder.EndUpdate();
			}
		}
		private void addDomainToList(DataRow currentRow, int indent)
		{
			ItemType type = (ItemType)currentRow["child_reptype_id"];
			int id = (int)currentRow["child_id"];

			if ( !this.AllowChangeDomain && id != this.DomainID )
				return;

			IRepositoryItem item = this.RepositoryService.GetItem(type, id, false);

			string text = currentRow["child_display"].ToString();
			string imgkey = currentRow.IsNull("child_image_key") ? item.ImageKey : currentRow["child_image_key"].ToString();

			// create domain item if current item is a domain
			DomainItem currentDomainItem = new DomainItem(imageList.Images[imgkey], indent, text, item, currentRow);
			tscmbDomain.Items.Add(currentDomainItem);

			// get child domains
			DataRow[] rows = _dtHierarchy.Select(string.Format(
					"parent_reptype_id = {0} AND parent_id = {1} AND child_reptype_id = {2}",
					(int)type, id, (int)ItemType.Domain));

			foreach ( DataRow row in rows ) {
				addDomainToList(row, indent + 1);
			}
		}
		private void addFoldersToDomain(DomainItem domain, DataRow currentRow, int indent,
										FolderItem parentFolder)
		{
			ItemType type = ItemType.Undefined;
			int id = -1;
			FolderItem currentFolder = null;
			if ( currentRow != null ) {
				// add current row to folder list
				type = (ItemType)currentRow["child_reptype_id"];
				id = (int)currentRow["child_id"];
				if ( type == ItemType.GenericFolder ) {
					GenericFolder folder = this.RepositoryService.GetItem(type, id, false) as GenericFolder;
					List<ItemType> ftypes = folder.AllowedChildTypes;
					if ( !this.ShowAllFolders &&
						 ( !folder.AllowedChildTypes.Contains(_folderType) ||
						   ( !folder.IsUserFolder && folder.AllowedChildTypes.Count > 0 &&
							  folder.AllowedChildTypes[0] != _folderType ) ) ) {
						return;
					}
					Repository.Workflow wf = _item as Repository.Workflow;
					if ( _item.RepositoryItemType == ItemType.GenericFolder ||
						 ftypes.Contains(_item.RepositoryItemType) ||
						 ( wf != null && ftypes.Contains(wf.FolderType) ) ) {
						string text = currentRow["child_display"].ToString();
						string imgkey = currentRow.IsNull("child_image_key") ? folder.ImageKey : currentRow["child_image_key"].ToString();
						currentFolder = new FolderItem(imageList.Images[imgkey], indent, text, folder, currentRow, parentFolder);
						domain.FolderItems.Add(currentFolder);
					} else {
						indent--;
					}
				} else if ( type == ItemType.BPolicy ) {
					if ( !existsFolderItemInList(domain.FolderItems, type, id) ) {
						BusinessPolicy policy = this.RepositoryService.GetItem(type, id, false) as BusinessPolicy;
						string text = currentRow["child_display"].ToString();
						string imgkey = currentRow.IsNull("child_image_key") ? policy.ImageKey : currentRow["child_image_key"].ToString();
						currentFolder = new FolderItem(imageList.Images[imgkey], indent, text, policy, currentRow, parentFolder);
						domain.FolderItems.Add(currentFolder);
					}
				} else if ( type == ItemType.LogicalMethodGroup ) {
					if ( !existsFolderItemInList(domain.FolderItems, type, id) ) {
						LogicalMethodGroup lmgroup = this.RepositoryService.GetItem(type, id, false) as LogicalMethodGroup;
						string text = currentRow["child_display"].ToString();
						string imgkey = currentRow.IsNull("child_image_key") ? lmgroup.ImageKey : currentRow["child_image_key"].ToString();
						currentFolder = new FolderItem(imageList.Images[imgkey], indent, text, lmgroup, currentRow, parentFolder);
						domain.FolderItems.Add(currentFolder);
					}
				} else if ( type == ItemType.Capability ) {
					if ( !existsFolderItemInList(domain.FolderItems, type, id) ) {
						Capability cap = this.RepositoryService.GetItem(type, id, false) as Capability;
						string text = currentRow["child_display"].ToString();
						string imgkey = currentRow.IsNull("child_image_key") ? cap.ImageKey : currentRow["child_image_key"].ToString();
						currentFolder = new FolderItem(imageList.Images[imgkey], indent, text, cap, currentRow, parentFolder);
						domain.FolderItems.Add(currentFolder);
					}
				} else if ( type == ItemType.Composite ) {
					if ( !existsFolderItemInList(domain.FolderItems, type, id) ) {
						ServiceModule svcmod = this.RepositoryService.GetItem(type, id, false) as ServiceModule;
						string text = currentRow["child_display"].ToString();
						string imgkey = currentRow.IsNull("child_image_key") ? svcmod.ImageKey : currentRow["child_image_key"].ToString();
						currentFolder = new FolderItem(imageList.Images[imgkey], indent, text, svcmod, currentRow, parentFolder);
						domain.FolderItems.Add(currentFolder);
					}
				} else {
					return;
				}
			}
			// get child folders
			DataRow[] rows;
			if ( currentRow == null ) {
				// if parent item is not a folder: add parent item to folder combobox
				if ( _parentItem != null && _parentItem.RepositoryItemType != ItemType.GenericFolder &&
					 !existsFolderItemInList(domain.FolderItems, _parentItem.RepositoryItemType, _parentItem.ID) ) {
					domain.FolderItems.Insert(0,
						new FolderItem(_parentItem.Image, 0, _parentItem.Name, _parentItem, null, null));
				}
				// of current domain
				rows = _dtHierarchy.Select(string.Format(
						"parent_reptype_id = {0} AND parent_id = {1} AND child_reptype_id = {2}",
						(int)ItemType.Domain, domain.Item.ID, (int)ItemType.GenericFolder),
							"child_display ASC");
			} else {
				// of current folder
				if ( this._folderType == ItemType.BRule ) {
					rows = _dtHierarchy.Select(string.Format(
							"parent_reptype_id = {0} AND parent_id = {1} AND " +
							"( child_reptype_id = {2} OR child_reptype_id = {3} )",
							(int)type, id, (int)ItemType.GenericFolder, (int)ItemType.BPolicy),
							"child_display ASC");
				} else if ( this._folderType == ItemType.LogicalWebMethod ) {
					rows = _dtHierarchy.Select(string.Format(
							"parent_reptype_id = {0} AND parent_id = {1} AND " +
							"( child_reptype_id = {2} OR child_reptype_id = {3} )",
							(int)type, id, (int)ItemType.GenericFolder, (int)ItemType.LogicalMethodGroup),
							"child_display ASC");
				} else if ( this._folderType == ItemType.Composite && this._item.RepositoryItemType == ItemType.Verb ) {
					rows = _dtHierarchy.Select(string.Format(
							"parent_reptype_id = {0} AND parent_id = {1} AND " +
							"( child_reptype_id = {2} OR child_reptype_id = {3} )",
							(int)type, id, (int)ItemType.GenericFolder, (int)ItemType.Composite),
							"child_display ASC");
				} else {
					rows = _dtHierarchy.Select(string.Format(
							"parent_reptype_id = {0} AND parent_id = {1} AND child_reptype_id = {2}",
							(int)type, id, (int)ItemType.GenericFolder),
							"child_display ASC");
				}
			}
			foreach ( DataRow row in rows ) {
				addFoldersToDomain(domain, row, indent + 1, currentFolder);
			}
		}
		private void addDomainItem(DomainItem item)
		{
			tscmbDomain.Items.Add(item);
		}

		private void fillFolderComboBox(DomainItem domainItem)
		{
			tscmbFolder.BeginUpdate();
			try {
				if ( domainItem.FolderItems.Count == 0 ) {
					//fillDomainListRecursive(domainItem.Row, 0, domainItem, false);
					if ( this.AddNullFolderItem ) {
						domainItem.FolderItems.Add(new FolderItem(null, 0, this.NullFolderItemText, null, null, null));
					}
					addFoldersToDomain(domainItem, null, -1, null);
				}
				tscmbFolder.Items.Clear();
				tscmbFolder.Items.AddRange(domainItem.FolderItems.ToArray());
				// auto-width combobox dropdown
				tscmbFolder.ComboBox.DropDownWidth = tscmbFolder.ComboBox.Width;
				using ( Graphics g = tscmbFolder.ComboBox.CreateGraphics() ) {
					foreach ( FolderItem item in tscmbFolder.Items ) {
						SizeF sz = g.MeasureString(item.Text, tscmbFolder.Font);
						int itemwidth = (int)Math.Ceiling(sz.Width) + ( item.Indent * IndentWidth ) +
										TextGap + 25/*scrollbar*/;
						if ( itemwidth > tscmbFolder.DropDownWidth )
							tscmbFolder.DropDownWidth = itemwidth;
					}
				}
			} finally {
				tscmbFolder.EndUpdate();
			}
		}
		private void selectDomain(int id)
		{
			DomainItem diSelect = null;
			foreach ( DomainItem di in tscmbDomain.Items ) {
				if ( di.Item.ID == id ) {
					diSelect = di;
					break;
				}
			}
			if ( diSelect != null )
				tscmbDomain.SelectedItem = diSelect;
		}
		private void selectFolderItem(ItemType type, int id)
		{
			FolderItem fiSelect = null;
			foreach ( FolderItem fi in tscmbFolder.Items ) {
				if ( fi.Item != null && fi.Item.RepositoryItemType == type && fi.Item.ID == id ) {
					fiSelect = fi;
					break;
				}
			}
			if ( fiSelect != null )
				tscmbFolder.SelectedItem = fiSelect;
		}
		private bool existsFolderItemInList(IEnumerable<FolderItem> items, ItemType type, int id)
		{
			foreach ( FolderItem fi in items ) {
				if ( fi.Item != null && fi.Item.RepositoryItemType == type && fi.Item.ID == id ) {
					return true;
				}
			}
			return false;
		}

		#endregion

		#region Event Handlers

		private void btnOK_Click(object sender, EventArgs e)
		{
			CancelEventArgs ceargs = new CancelEventArgs(false);
			OnValidateNewItem(ceargs);
			if ( !ceargs.Cancel )
				OnSaveClose(new CancelEventArgs(false));
		}

		private void tsbtnSaveClose_Click(object sender, EventArgs e)
		{
			CancelEventArgs ceargs = new CancelEventArgs(false);
			OnValidateNewItem(ceargs);
			if ( !ceargs.Cancel )
				OnSaveClose(new CancelEventArgs(false));
		}
		private void tsbtnSaveContinue_Click(object sender, EventArgs e)
		{
			CancelEventArgs ceargs = new CancelEventArgs(false);
			OnValidateNewItem(ceargs);
			if ( !ceargs.Cancel )
				OnSaveContinue(new CancelEventArgs(false));
		}
		private void tsbtnCancel_Click(object sender, EventArgs e)
		{
			OnCancel();
		}

		private void tscmbDomain_SelectedIndexChanged(object sender, EventArgs e)
		{
			OnDomainSelectedIndexChanged();
		}
		private void tscmbFolder_SelectedIndexChanged(object sender, EventArgs e)
		{
			OnFolderSelectedIndexChanged();
		}

		private void ComboBox_DrawItem(object sender, DrawItemEventArgs e)
		{
			ComboBox cmb = sender as ComboBox;
			if ( cmb == null )
				return;

			e.DrawBackground();
			if ( ( e.State & DrawItemState.Focus ) == DrawItemState.Focus )
				e.DrawFocusRectangle();

			if ( e.Index < 0 || e.Index >= cmb.Items.Count ) {
				using ( StringFormat sf = new StringFormat() ) {
					sf.Trimming = StringTrimming.None;
					sf.FormatFlags = StringFormatFlags.LineLimit | StringFormatFlags.NoWrap;
					sf.Alignment = StringAlignment.Center;
					sf.LineAlignment = StringAlignment.Center;
					string txt = "- No Folder Selected -";
					if ( sender == tscmbDomain.ComboBox )
						txt = "- No Domain Selected -";
					e.Graphics.DrawString(txt, e.Font, SystemBrushes.GrayText, e.Bounds, sf);
				}
			} else {
				FolderItem item = cmb.Items[e.Index] as FolderItem;
				if ( item != null ) {
					int indent = IndentWidth * item.Indent + 2;
					int textGap = 0;

					// draw image
					if ( item.Image != null ) {
						textGap = TextGap;
						Rectangle rectImg = new Rectangle(e.Bounds.X + indent, e.Bounds.Y,
														  TextGap, e.Bounds.Height);
						e.Graphics.DrawImageUnscaled(item.Image, rectImg);
					}
					// draw text
					RectangleF rectText = new RectangleF(e.Bounds.Left + textGap + indent, e.Bounds.Y,
														 e.Bounds.Width - textGap - indent, e.Bounds.Height);
					using ( StringFormat sf = new StringFormat() )
					using ( Brush b = new SolidBrush(e.ForeColor) ) {
						sf.Trimming = StringTrimming.EllipsisCharacter;
						sf.Alignment = StringAlignment.Near;
						sf.LineAlignment = StringAlignment.Center;
						e.Graphics.DrawString(item.Text, e.Font, b, rectText, sf);
					}

				} else {
					using ( StringFormat sf = new StringFormat() )
					using ( Brush b = new SolidBrush(e.ForeColor) ) {
						sf.Trimming = StringTrimming.EllipsisCharacter;
						sf.Alignment = StringAlignment.Near;
						sf.LineAlignment = StringAlignment.Center;
						e.Graphics.DrawString(cmb.Items[e.Index].ToString(), e.Font, b, e.Bounds, sf);
					}
				}
			}
		}

		#endregion


		#endregion
	}
}